/*
 * list.c
 *
 *  Created on: Nov 26, 2008
 *      Author: marco
 */

#include <stdio.h>
#include <stdlib.h>
#include "list.h"

#define OK 0
#define ERROR 1

list new_node(int v) {
	list aux;
	aux = malloc(sizeof(node));
	if (aux != NULL) {
		aux->val = v;
		aux->next = NULL;
	}
	return aux;
}

void free_node(list l) {
	if ((l == NULL) || (l->next != NULL))
		printf("freeNode: errore, lista vuota o con piu' di un nodo\n");
	else
		free(l);
}



void insert (list l, list n){
    if ( l == NULL )
	printf("insertNext: errore, la lista iniziale e' vuota\n");
    else  if (n->next != NULL)
	printf("insertNext: errore, la lista da inserire ha piu' di un elemento\n");
    else if ( l == NULL ) /* niente da inserire */
	return ;
    else {
        /* qua la lista l ha almeno un elemento ed n ne ha esattamente uno */
	node* tmp;
	tmp = l->next;
	l->next = n;
	n->next = tmp;
    }
}






list del_next(list l) {
	if (l == NULL)
		return NULL;
	else if (l->next == NULL)
		return NULL;
	else {
		list tmp = l->next;
		l->next = l->next->next;
		return tmp;
	}
}

int val(list l) {
	if (l == NULL)
		return ERROR;
	else
		// MA SERVE QUI L'ELSE?
		return l->val;

}

list next(list l) {
	if (l == NULL)
		return 0; // perchè non null?
	else
		return l->next;
}

//list map(int(*f)(int), list l) {
//	//int i = 0;
//	list aux = NULL;
//	if (l == NULL)
//		return NULL;
//	else {
//
//		list tmp;
//
//		aux = new_node(f(l->val));
//		do { //così skippa l'ultimo
//			tmp = new_node(f(l->val));
//			insert(aux, tmp);
//			//printf("*l:%p  *tmp:%p", l, tmp);
//			l = l->next;
//		} while (l != NULL);
//
//	}
//	return aux;
//}

list map (int(*f)(int), list l) {


	if (l == NULL) {
		return NULL;
	}

	list first = new_node(f(l->val));

	l = next(l);


	while ( l != NULL ) {
		list tmp = NULL;
		printf("l[%d]", l->val);
		tmp = new_node(f(l->val));
		insert(first, tmp);
		l = next(l);
	}

//	do {
//		//list tmp = NULL;
//		printf("l %d", l->val);
//		l = next(l);
//		printf("l next %d", l->val);
//
//
//		list tmp = new_node(f(l->val));
//		insert (first, tmp);
//	} while (l != NULL);

	return first;

}




int reduce(int(*f)(int, int), int en, list l) {
	int tmp = en;
	if (l == NULL) // forse if cosi inutile per la formulazione della funzione
		return en;
	else {

		while (l->next !=NULL) {
			tmp = f(tmp, l->val);
			l = l->next;
		}
		tmp = f(tmp, l->val);

//		while (l->next != NULL) {
//			tmp = f(tmp, l->val);
//			l = l->next;
//		}
//		tmp = f(tmp, l->val);
//		tmp = f(tmp, en);
	}

	return tmp;
}
